<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>封装集合</title>
  </head>
  <body>
    <script type="text/javascript">
      function Set() {
        //属性
        this.items = {}

        //has 方法 判断集合是否存在value
        Set.prototype.has = function(value) {
          return this.items.hasOwnProperty(value)
        }

        // 1.add 方法  添加元素到集合
        Set.prototype.add = function(value) {
          // 1.判断集合中是否已经包含了该元素
          if (this.has(value)) return false

          // 2.将元素添加到集合中
          this.items[value] = value
          return true
        }

        // 2.remove方法 从集合中删除某个元素
        Set.prototype.remove = function(value) {
          // 1.判断集合中是否包含该元素
          if (!this.has(value)) return false

          // 2.包含该元素, 那么将元素删除
          delete this.items[value]
          return true
        }

        // 3.clear方法  清空集合中所有的元素
        Set.prototype.clear = function() {
          this.items = {}
        }

        // 4.size方法 获取集合的大小
        Set.prototype.size = function() {
          return Object.keys(this.items).length

          /*
          考虑兼容性问题, 使用下面的代码
          var count = 0
          for (var value in this.items) {
              if (this.items.hasOwnProperty(value)) {
                  count++
              }
          }
          return count
          */
        }

        // 5.values  获取集合中所有的值
        Set.prototype.values = function() {
          return Object.keys(this.items)

          /*
          考虑兼容性问题, 使用下面的代码
          var keys = []
          for (var value in this.items) {
              keys.push(value)
          }
          return keys
          */
        }

        //6.union方法 求并集
        Set.prototype.union = function(otherSet) {
          // this  集合A
          // otherSet 集合B
          // 创建新集合
          let unionSet = new Set()
          // 将集合A中的所有元素添加到新集合中
          let values = this.values()
          for (let i = 0; i < values.length; i++) {
            unionSet.add(values[i])
          }
          // 取出集合B的值判断是否需要加入新集合  不需要判断因为add方法进行判断了
          values = otherSet.values()
          for (let i = 0; i < values.length; i++) {
            unionSet.add(values[i])
          }
          return unionSet
        }

        // 7.interSection 求交集
        Set.prototype.interSection = function(otherSet) {
          // this  集合A
          // otherSet 集合B
          // 创建新集合
          let interSection = new Set()
          // 判断是否存在集合B
          let values = this.values()
          for (let i = 0; i < values.length; i++) {
            let items = values[i]
            if (otherSet.has(items)) {
              interSection.add(items)
            }
          }
          return interSection
        }
        Set.prototype.difference = function(otherSet) {
          // this  集合A
          // otherSet 集合B
          // 创建新集合
          let difference = new Set()
          // 判断是否存在集合B
          let values = this.values()
          for (let i = 0; i < values.length; i++) {
            let items = values[i]
            if (!otherSet.has(items)) {
              difference.add(items)
            }
          }
          return difference
        }
        // 子集
        Set.prototype.subset = function(otherSet){
          // this  集合A
          // otherSet 集合B
          // 遍历集合A
          let values = this.values()
          for(let i =0;i<values.length;i++){
            let items = values[i]
            if(!otherSet.has(items)){
              return false
            }
          }
          return true
        }
      }
      /* 
       // 测试和使用集合类 
       let set = new Set()

       // 添加元素
       set.add(1)
       alert(set.values()) // 1
       set.add(1)
       alert(set.values()) // 1

       set.add(100)
       set.add(200)
       alert(set.values()) // 1,100,200

       // 判断是否包含元素
       alert(set.has(100)) // true

       // 删除元素
       set.remove(100)
       alert(set.values()) // 1, 200

       // 获取集合的大小
       alert(set.size()) // 2
       set.clear()
       alert(set.size()) // 0
       */

      let setA = new Set()
      setA.add(100)
      setA.add(200)
      setA.add(300)
      let setB = new Set()
      setB.add(100)
      setB.add(500)
      setB.add(600)
      
      //并集
      let unionSet = setA.union(setB)
      alert(unionSet.values())
      // 交集
      let interSection = setA.interSection(setB)
      alert(interSection.values())
      // 差集
      let difference = setA.difference(setB)
      alert(difference.values())
      let subset = setA.subset(setB)
       alert(subset)
       
    </script>
  </body>

</html>
